import { Direction, Position, Food, FoodType, GameSettings } from '../types/game';
import { GAME_SETTINGS, FOOD_DURATION } from '../config/gameConfig';

export const getInitialSnakePosition = (): Position[] => {
  const centerX = Math.floor(GAME_SETTINGS.GRID_SIZE / 2);
  const centerY = Math.floor(GAME_SETTINGS.GRID_SIZE / 2);
  
  const snake: Position[] = [];
  for (let i = 0; i < GAME_SETTINGS.INITIAL_SNAKE_LENGTH; i++) {
    snake.push({ x: centerX, y: centerY - i });
  }
  return snake;
};

export const generateFood = (snake: Position[], score: number): Food => {
  const position = generateRandomPosition(snake);
  const now = Date.now();
  
  // 根据分数调整食物类型概率
  const foodTypeRoll = Math.random();
  let foodType = FoodType.NORMAL;
  let cumulativeProbability = 0;
  
  for (const [type, settings] of Object.entries(GAME_SETTINGS.FOOD_TYPES)) {
    cumulativeProbability += settings.probability;
    if (foodTypeRoll <= cumulativeProbability) {
      foodType = type as FoodType;
      break;
    }
  }

  return {
    ...position,
    type: foodType,
    points: GAME_SETTINGS.FOOD_TYPES[foodType].points,
    expiresAt: now + FOOD_DURATION
  };
};

export const generateRandomPosition = (snake: Position[]): Position => {
  let position: Position;
  do {
    position = {
      x: Math.floor(Math.random() * GAME_SETTINGS.GRID_SIZE),
      y: Math.floor(Math.random() * GAME_SETTINGS.GRID_SIZE)
    };
  } while (snake.some(segment => segment.x === position.x && segment.y === position.y));
  return position;
};

export const getNextPosition = (head: Position, direction: Direction): Position => {
  const newPosition = { ...head };
  switch (direction) {
    case Direction.UP:
      newPosition.y -= 1;
      break;
    case Direction.DOWN:
      newPosition.y += 1;
      break;
    case Direction.LEFT:
      newPosition.x -= 1;
      break;
    case Direction.RIGHT:
      newPosition.x += 1;
      break;
    default:
      return newPosition;
  }
  return newPosition;
};

export const checkCollision = (position: Position): boolean => {
  return (
    position.x < 0 ||
    position.x >= GAME_SETTINGS.GRID_SIZE ||
    position.y < 0 ||
    position.y >= GAME_SETTINGS.GRID_SIZE
  );
};

export const checkSelfCollision = (head: Position, snake: Position[]): boolean => {
  return snake.some(segment => segment.x === head.x && segment.y === head.y);
};

export const calculateSpeed = (score: number, settings: GameSettings): number => {
  const speedIncrease = Math.floor(score / settings.speedIncrementScore) * (settings.speedIncrementPercent / 100);
  const speed = settings.baseSpeed / (1 + speedIncrease);
  return Math.max(speed, settings.maxSpeed);
};

export const isValidDirection = (currentDirection: Direction, newDirection: Direction): boolean => {
  const opposites: Record<Direction, Direction> = {
    [Direction.UP]: Direction.DOWN,
    [Direction.DOWN]: Direction.UP,
    [Direction.LEFT]: Direction.RIGHT,
    [Direction.RIGHT]: Direction.LEFT
  };
  return opposites[currentDirection] !== newDirection;
};

export const getOppositeDirection = (direction: Direction): Direction => {
  switch (direction) {
    case Direction.UP:
      return Direction.DOWN;
    case Direction.DOWN:
      return Direction.UP;
    case Direction.LEFT:
      return Direction.RIGHT;
    case Direction.RIGHT:
      return Direction.LEFT;
  }
};

export const getRandomDirection = (): Direction => {
  const directions = [Direction.UP, Direction.DOWN, Direction.LEFT, Direction.RIGHT];
  return directions[Math.floor(Math.random() * directions.length)];
}; 